﻿@page "/Account/Manage/ChangePassword"

@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Identity
@using MyApp.Data
@using MyApp.Identity

@inject UserManager<ApplicationUser> UserManager
@inject SignInManager<ApplicationUser> SignInManager
@inject UserAccessor UserAccessor
@inject IdentityRedirectManager RedirectManager
@inject ILogger<ChangePassword> Logger

<PageTitle>Change password</PageTitle>

<Heading3>Change password</Heading3>

<div class="max-w-xl">
    <StatusMessage Message="@_message" />

    <div class="mt-3 shadow overflow-hidden sm:rounded-md">
        <div class="px-4 bg-white dark:bg-black sm:p-6">
            <EditForm id="change-password-form" Model="Input" FormName="change-password" OnValidSubmit="OnValidSubmitAsync" method="post">
                <DataAnnotationsValidator />
                <ValidationSummary class="mb-3 text-danger text-center font-semibold" />
                
                <div class="flex flex-col gap-4">
                    <div>
                        <label for="old-password" class="@TextInput.LabelClasses">Old password</label>
                        <div class="mt-1 relative rounded-md shadow-sm">
                            <InputText id="old-password" type="password" @bind-Value="Input.OldPassword" class="@TextInput.InputClasses" autocomplete="current-password" aria-required="true" placeholder="Please enter your old password." />
                        </div>
                        <ValidationMessage For="() => Input.OldPassword" class="mt-2 text-danger text-sm" />
                    </div>
                    <div>
                        <label for="new-password" class="@TextInput.LabelClasses">New password</label>
                        <div class="mt-1 relative rounded-md shadow-sm">
                            <InputText id="new-password" type="password" @bind-Value="Input.NewPassword" class="@TextInput.InputClasses" autocomplete="new-password" aria-required="true" placeholder="Please enter your new password." />
                        </div>
                        <ValidationMessage For="() => Input.NewPassword" class="mt-2 text-danger text-sm" />
                    </div>
                    <div>
                        <label for="confirm-password" class="@TextInput.LabelClasses">Confirm password</label>
                        <div class="mt-1 relative rounded-md shadow-sm">
                            <InputText id="confirm-password" type="password" @bind-Value="Input.ConfirmPassword" class="@TextInput.InputClasses" autocomplete="new-password" aria-required="true" placeholder="Please confirm your new password." />
                        </div>
                        <ValidationMessage For="() => Input.ConfirmPassword" class="mt-2 text-danger text-sm" />
                    </div>
                    <div>
                        <PrimaryButton type="submit">Update password</PrimaryButton>
                    </div>
                </div>
            </EditForm>
        </div>
    </div>
</div>

@code {
    private string? _message;
    private ApplicationUser _user = default!;
    private bool _hasPassword;

    [SupplyParameterFromForm]
    private InputModel Input { get; set; } = default!;

    protected override async Task OnInitializedAsync()
    {
        Input ??= new();

        _user = await UserAccessor.GetRequiredUserAsync();
        _hasPassword = await UserManager.HasPasswordAsync(_user);
        if (!_hasPassword)
        {
            RedirectManager.RedirectTo("/Account/Manage/SetPassword");
            return;
        }
    }

    private async Task OnValidSubmitAsync()
    {
        var changePasswordResult = await UserManager.ChangePasswordAsync(_user, Input.OldPassword!, Input.NewPassword!);
        if (!changePasswordResult.Succeeded)
        {
            _message = $"Error: {string.Join(",", changePasswordResult.Errors.Select(error => error.Description))}";
            return;
        }

        await SignInManager.RefreshSignInAsync(_user);
        Logger.LogInformation("User changed their password successfully.");

        RedirectManager.RedirectToCurrentPageWithStatus("Your password has been changed");
    }

    private sealed class InputModel
    {
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Current password")]
        public string? OldPassword { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "New password")]
        public string? NewPassword { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm new password")]
        [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
        public string? ConfirmPassword { get; set; }
    }
}
